package com.question.common.aspect;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.question.business.auth.model.dto.UserDetailDTO;
import com.question.common.constants.NumberConstants;
import com.question.common.utils.CurrentUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Objects;

/**
 * 接口日志
 *
 * @author star
 * @since 2023/9/6
 */
@Slf4j
@Aspect
@Component
public class RequestLogAspect {

    @Resource
    private HttpServletRequest request;

    @Resource
    private CurrentUserUtil currentUserUtil;

    @Pointcut("execution(* com.question.business.*.controller.*Controller.*(..))")
    public void pointcut() {

    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        String params = null;
        Object[] args = point.getArgs();
        if (Objects.nonNull(args)) {
            Object[] filterArgs = Arrays.stream(args).filter(o -> (!(o instanceof HttpServletRequest) && !(o instanceof HttpServletResponse))).toArray();
            if (filterArgs.length == NumberConstants.ONE) {
                params = JSON.toJSONString(filterArgs[0]);
            } else {
                params = JSON.toJSONString(filterArgs);
            }
        }
        // 获取token
        String token = currentUserUtil.getToken(request);
        UserDetailDTO user = null;
        if (StringUtils.isNotBlank(token)) {
            user = currentUserUtil.getUser();
        }
        log.info("开始请求接口：{} 用户：{} 参数：{}", request.getRequestURI(), Objects.nonNull(user) ? user.getUsername() : null, params);
        Object result = point.proceed();
        long endTime = System.currentTimeMillis();
        log.info("结束请求接口：{} 耗时：{}毫秒", request.getRequestURI(), (endTime - startTime));
        return result;
    }

}
